/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tubes1sister.peerConnection.clientAsServer;

import java.io.*;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Arrays;
import tubes1sister.metainfo;
import tubes1sister.peerConnection.message.Handshake;
import tubes1sister.peerConnection.message.MessageFlow;
import tubes1sister.tools.DirectorySearchHelper;
import tubes1sister.tools.FileProcessor;
import tubes1sister.tools.Timer;
import tubes1sister.tools.debug;

/**
 *
 * @author Muhammad Anis
 */
public class clientServerHandler implements Runnable {
    //konstruktor

    Socket server;
    //pesan yang ditangkap dari client    
    String message;
    Timer timer;
    public boolean isTimeout = false;
    public String rootDirectory;
    public byte[] pieces;
    //konstruktor

    public clientServerHandler(Socket server,String rootDirectory) {
        this.server = server;
        this.rootDirectory = rootDirectory;
    }

    public void run() {
        try {
            message = "";
            DataInputStream dis = new DataInputStream(server.getInputStream());
            DataOutputStream dos = new DataOutputStream(server.getOutputStream());
            InetAddress addr = server.getInetAddress();

            timer = new Timer(10000, "clientServerHandler");
            timer.start();
            timer.reset();

            System.out.println("Client As Server Handler Starting");
            System.out.println("Menerima Permintaan dari Client: " + addr.getHostAddress());
            //menerima pesan
            byte[] pesan = new byte[71];
            int read = dis.read(pesan);
            timer.reset();
            message = new String(pesan);
            debug.debugObject(read);
            //balas dengan bitfield
            if (message.indexOf("BitTorrentProtocol") != -1) {
                //berarti tipe handshake
                //balas dengan bitfield message
                debug.debugObject("----------------CLIENT SERVER HANDLE IS RUNNING------------");
                String filename = Handshake.parseHandshakeMessage(message);
                int indexPiece = Handshake.getPieceIndex(message);
                System.out.println("Filename yang dicari: " + filename);
                DirectorySearchHelper dsh = new DirectorySearchHelper(rootDirectory);                
                String getFileName = dsh.isHasFile(filename);                
                if (getFileName != null) {
                    //cek bitfieldnya
                    //dapatkan file metainfonya
                    FileProcessor fp = new FileProcessor(getFileName + ".torrent", 1);
                    metainfo meta = fp.ProcessMetainfoData();
                    int pieceLength = meta.piecelength;
                    String nilaiHash = fp.getHashValue();
                    //cek antara file dengan nilai hashnya
                    try {
                        String partHash = getHashValue(nilaiHash, indexPiece);
                        pieces = dsh.getBitField(getFileName,partHash , pieceLength, indexPiece);
                        if(pieces.length < pieceLength){
                            pieces = Arrays.copyOf(pieces, pieceLength);
                        }
                    } catch (Exception e) {
                        System.err.println(e.getMessage());
                    }
                     String partHash = getHashValue(nilaiHash, indexPiece);
                    String balasan = MessageFlow.generateBitfieldMessage(getFileName,  partHash, pieceLength, indexPiece);
                    byte[] balasanHandshake = balasan.getBytes();
                    dos.write(balasanHandshake);
                    dos.flush();
                    //terima balasan berupa koneksi
                    byte[] balasanBitField = new byte[5+Integer.toString(indexPiece).length()];
                    int read1 = dis.read(balasanBitField);
                    String balasanBitFieldString = new String(balasanBitField);
                    debug.debugObject(balasanBitFieldString);
                    //balas dengan byte yang diinginkan
                    if(balasanBitFieldString.indexOf("00136")==-1){
                        return;
                    } else{
                        dos.write(pieces);
                        dos.flush();
                        //menerima
                        
                    }
                }
            } else {
                //hentikan koneksi
                return;
            }
            //tunggu balasan dari client berupa pieces ke berapa yang ingin dia download
        } catch (Exception e) {
            debug.debugObject(e.getMessage());
        }
    }
    
    public String getHashValue(String fullHash,int index){
        if(index + 40 > fullHash.length())
            return null;
        else
            return fullHash.substring(index*40, index*40+40);
    }
}
